package particles;

import bpmjs.Stats;
import bpmjs.HtmlDef;
import bpmjs.Matrix4;
import bpmjs.Camera;
import bpmjs.Color;

import js.Lib;
import js.Dom;

using bpmjs.MooToolsAdapter;

class CanvasParticleRenderer
{
	var model : EngineModel;
	
	var canvas : Canvas;
	var context : CanvasRenderingContext2D;
	
	public function new(model : EngineModel)
	{
		this.model = model;
		
		var content = Lib.document.getElementById("content");
		
		canvas = Lib.document.createCanvas();
		canvas.onmousemove = onMouseMove;
		content.appendChild(canvas);
		
		context = canvas.getContext2D();
		
		Lib.window.onresize = onResize;
		updateSize();
	}
	
	public function render()
	{
		Stats.measureFPS();
		Stats.addMessage("p:" + model.particles.length);
		
		model.time = Date.now().getTime();
		
		context.globalCompositeOperation = "source-over";
		context.fillStyle = Color.toContextRGBA(0x2E, 0x2B, 0x32, (Math.sin(model.time / 5555) / 2 + 0.5) * 0.6 + 0.4);
        context.fillRect(0,0, canvas.width, canvas.height);
		context.globalCompositeOperation = "lighter";
		
		for (particle in model.particles)
		{
			switch(particle.form)
			{
				case 0:
					renderParticle(particle);
				case 1:
					renderParticleDot(particle);
				case 2:
					renderParticleCross(particle);
			}
		}
	}
	
	function onResize(event : Event)
	{
		updateSize();
	}
	
	function onMouseMove(event : Event)
	{
		model.mouseX = event.clientX;
		model.mouseY = event.clientY;
	}
	
	function updateSize()
	{
		model.width = Lib.window.innerWidth; 
		model.height = Lib.window.innerHeight;
		
		canvas.width = model.width;
		canvas.height = model.height;
	}
	
	function renderParticle(particle : Particle2)
	{
		var size = 12;
		var alpha = (1 - (particle.age / particle.ageDead)) * 1.5;
		
		if (particle.age < 10)
			alpha = particle.age / 10;
		
		var x = particle.x - size / 2; 
		var y = particle.y - size / 2;
		
		x /= 2;
		y /= 2;
		
		var halfSize = size / 2;
		var sizeSmall = 0;
		var radgrad = context.createRadialGradient( x + halfSize, y + halfSize, sizeSmall, x + halfSize, y + halfSize, halfSize);  
        radgrad.addColorStop(0, Color.toContextRGBA(particle.r, particle.g, particle.b, alpha));
        radgrad.addColorStop(1, Color.toContextRGBA(0x2E, 0x2B, 0x32, 0.0));
        context.fillStyle = radgrad;
        context.fillRect(x,y, size, size);

		var rx = Math.cos(particle.angle) * 15;
		var ry = Math.sin(particle.angle) * 15;
		context.strokeStyle = Color.toContextRGBA(particle.r, particle.g, particle.b, alpha / 2);
		context.lineWidth = 1;
        context.beginPath();
        context.moveTo(x + size / 2, y + size / 2);
        context.lineTo(x + size / 2 + rx, y + size / 2 + ry);
        context.stroke();
	}
	
	function renderParticleDot(particle : Particle2)
	{
		var size = 2;
		var alpha = 1 - (particle.age / particle.ageDead) + Math.cos(particle.angle * 5) * 0.25;
		
		var x = particle.x - size / 2; 
		var y = particle.y - size / 2;
		
		x /= 2;
		y /= 2;
		
        context.fillStyle = Color.toContextRGBA(particle.r, particle.g, particle.b, alpha);
        context.fillRect(x,y, size, size);
	}
	
	function renderParticleCross(particle : Particle2)
	{
		var alpha = 1 - (particle.age / particle.ageDead) + Math.cos(particle.angle * 5) * 0.25;
		
		var x = particle.x; 
		var y = particle.y;
		x /= 2;
		y /= 2;

		context.strokeStyle = Color.toContextRGBA(particle.r, particle.g, particle.b, alpha / 2);
		context.lineWidth = 1;
        context.beginPath();
        
		for (i in 0 ... 4)
		{		
			var rx = Math.cos(particle.angle + i * Math.PI / 2) * 4;
			var ry = -Math.sin(particle.angle + i * Math.PI / 2) * 4;
			
	        context.moveTo(x, y);
	        context.lineTo(x + rx, y + ry);
		}
		
        context.stroke();
	}
	
}
